package errors

import "fmt"

// Data 错误数据
type Data string

// Error 底层接口
func (data Data) Error() string {
	return string(data)
}

// New 创建错误代码
//  Type    CodeType	错误类型
//  Explain string		错误代码说明
func New(Type CodeType, Explain string) (code Code, err error) {
	code = CodeIota()
	err = CodeRecord.AddCode(code, &CodeConfig{
		Type:    Type,
		Explain: Explain,
	})
	return
}

// Recover 错误拦截
func Recover(code Code, err *error) {
	if errors := recover(); errors != nil {
		if e, ok := errors.(error); ok {
			*err = Add(code, e)
		} else {
			*err = AddStr(code, fmt.Sprint(e))
		}
	}
}

// Panic 抛出错误
func Panic(code Code, err error) {
	if err != nil {
		panic(setAdd(code, err, 2))
	}
}

// Add 添加错误
func Add(code Code, err error) error {
	return setAdd(code, err, 2)
}

// AddStr 添加文本
func AddStr(code Code, str string) error {
	return setAdd(code, Data(str), 2)
}

// setError
func setAdd(code Code, err error, skip int) error {
	data := CodeData{Code: code, Data: err, Time: <-Ticker}
	// 限制调试才需要
	if config := data.GetConfig(); config.Type&CodeTypeDebug == CodeTypeDebug {
		data.Srack = Stack.Caller(skip)
	}
	code.TriggerEvent(data)
	return data
}
